# -*- coding: utf-8 -*- 
"""
Created by hcx on 17-7-20 下午2:36.
@author: 胡超翔
"""
from __future__ import absolute_import
from __future__ import unicode_literals

import logging

from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404
from django.urls import reverse_lazy
from django.views.generic import DetailView
from django.views.generic import FormView
from django.views.generic import View

from autodeploy import settings
from autodeploy.apps.common.search import SearchView
from autodeploy.apps.common.tasks import use_ansible
from autodeploy.apps.common.upload_file.upload_file import delete_dire
from autodeploy.apps.playbooks.forms import PlayBooksForm, PlayBooksFileForm
from autodeploy.apps.playbooks.models import PlayBooks, PlayBooksFile
from autodeploy.apps.server.models import Server, ServerManage

logger = logging.getLogger(__name__)


class DetailPlayBookView(LoginRequiredMixin, DetailView):
    """剧本详情"""
    template_name = 'playbooks/running.html'
    model = PlayBooks
    context_object_name = 'play_book'
    
    def get_context_data(self, **kwargs):
        context = super(DetailPlayBookView, self).get_context_data(**kwargs)
        manage = self.request.GET.get('manage', '')
        searchaction = self.request.GET.get('searchaction', '')
        if manage or searchaction:
            if manage:
                context['server_list'] = Server.objects.filter(server_manage_id=manage).filter(
                        ip__icontains=searchaction)
            else:
                context['server_list'] = Server.objects.filter(ip__icontains=searchaction)
        else:
            context['server_list'] = Server.objects.filter()
        context['manage_list'] = ServerManage.objects.filter()
        return context


class PlayBooksView(LoginRequiredMixin, View):
    """运行剧本"""
    
    def post(self, request, *args, **kwargs):
        result = 0
        self.pbid = request.GET.get('pbid', '')
        self.fid = request.GET.get('fid', '')
        self.sids = request.POST.getlist('sid', '')
        play_book = self.get_play_book()
        book_file = self.get_books_file()
        server_list = self.get_server()
        if server_list:
            for server in server_list:
                if play_book and book_file:
                    server.playbooks.add(play_book)
                try:
                    logger.info('启动celery***************')
                    use_ansible.delay(server_list, playbooks=book_file, variable=None)
                    logger.info('结束*************************')
                except Exception as e:
                    logger.error(e)
            
            result = 1
        return HttpResponse(result)
    
    def get_play_book(self):
        try:
            play_book = PlayBooks.objects.get(pk=self.pbid)
        except Exception as e:
            logger.error('未找到该剧本数据，错误信息:%s' % e)
            play_book = None
        return play_book
    
    def get_server(self):
        server_list = []
        for sid in self.sids:
            try:
                server = Server.objects.get(pk=sid)
            except Exception as e:
                logger.error('未找到该服务器数据，错误信息:%s' % e)
                pass
            else:
                server_list.append(server)
        return server_list
    
    def get_books_file(self):
        version = self.request.POST.get('version', '')
        try:
            if self.fid == '' and version != '':
                book_file = PlayBooksFile.objects.get(playbooks=self.get_play_book(), version=version)
            else:
                book_file = PlayBooksFile.objects.get(pk=self.fid)
        except Exception as e:
            logger.error('未找到该剧本数据，错误信息:%s' % e)
            book_file = None
        return book_file


class ListPlayBooksView(LoginRequiredMixin, SearchView):
    """剧本列表"""
    template_name = 'playbooks/list.html'
    model = PlayBooks
    context_object_name = 'play_books'
    name_list = ['name']

    # paginate_by = 2
    # paginate_orphans = 10
    def get_context_data(self, **kwargs):
        context = super(ListPlayBooksView, self).get_context_data(**kwargs)
        # context[self.context_object_name] = self.get_queryset()
        context[self.context_object_name] = self.search()
        context['server_list'] = Server.objects.filter()
        return context


class EditorPlayBookView(LoginRequiredMixin, FormView):
    """上传剧本"""
    template_name = 'playbooks/editor.html'
    form_class = PlayBooksForm
    success_url = reverse_lazy('playbooks:list')
    
    def get_form_kwargs(self):
        kwargs = super(EditorPlayBookView, self).get_form_kwargs()
        pbid = self.kwargs.get('pbid', None)  # 链接里的参数
        
        if pbid:
            self.play_book = get_object_or_404(PlayBooks, pk=int(pbid))
            kwargs['instance'] = self.play_book
        else:
            self.play_book = PlayBooks()
        return kwargs
    
    # def get_queryset(self):
    #
    #     return super(ProductAddEditView, self).get_queryset()
    
    def get_context_data(self, **kwargs):
        context = super(EditorPlayBookView, self).get_context_data(**kwargs)
        # 这里可以自己加参数
        context['pbid'] = self.play_book.id
        # context['product_type'] = self.product_type
        return context
    
    def form_valid(self, form):
        self.play_book = form.save()
        messages.info(self.request, '编辑剧本成功')
        return super(EditorPlayBookView, self).form_valid(form)


class DeletePlayBooksView(LoginRequiredMixin, View):
    """删除剧本"""
    
    def get(self, request, *args, **kwargs):
        result = 0  # 0是删除失败
        try:
            pbid = self.kwargs.get('pbid', None)
            play_book = PlayBooks.objects.get(pk=pbid)
            result = play_book.update_delete()
            logger.info(u'%s删除剧本成功%s' % (request.user, pbid))
        except Exception as e:
            logger.error(u'删除剧本出错,错误信息:%s' % e)
        
        return HttpResponse(result)


class EditorBookFileView(LoginRequiredMixin, FormView):
    """剧本版本创建"""
    template_name = 'playbooks/file_editor.html'
    form_class = PlayBooksFileForm
    
    # success_url = reverse_lazy('playbooks:file_list')
    def get_form_kwargs(self):
        kwargs = super(EditorBookFileView, self).get_form_kwargs()
        fid = self.kwargs.get('fid', None)  # 链接里的参数
        
        if fid:
            self.book_file = get_object_or_404(PlayBooksFile, pk=int(fid))
            kwargs['instance'] = self.book_file
        else:
            self.book_file = PlayBooksFile()
        return kwargs
    
    # def get_queryset(self):
    #
    #     return super(ProductAddEditView, self).get_queryset()
    
    def get_context_data(self, **kwargs):
        context = super(EditorBookFileView, self).get_context_data(**kwargs)
        # 这里可以自己加参数
        pbid = self.request.GET.get('pbid', '')
        context['fid'] = self.book_file.id
        if self.kwargs.get('fid', None):
            context['pbid'] = self.book_file.playbooks.id
            context['pb_name'] = self.book_file.playbooks.name
        elif pbid:
            context['pbid'] = pbid
            play_book = PlayBooks.objects.get(pk=pbid)
            context['pb_name'] = play_book.name
        return context
    
    def form_valid(self, form):
        self.book_file = form.save()
        messages.info(self.request, '编辑剧本成功')
        self.success_url = reverse_lazy('playbooks:file_list') + '?pbid=' + str(self.book_file.playbooks.id)
        return super(EditorBookFileView, self).form_valid(form)


class ListBookFileView(LoginRequiredMixin, SearchView):
    """剧本版本列表"""
    template_name = 'playbooks/file_list.html'
    model = PlayBooksFile
    context_object_name = 'file_list'
    name_list = ['version']

    def get_context_data(self, **kwargs):
        context = super(ListBookFileView, self).get_context_data(**kwargs)
        context[self.context_object_name] = self.get_files()
        context['pbid'] = self.pbid
        return context
    
    def get_files(self):
        self.pbid = self.request.GET.get('pbid', '')
        if self.pbid:
            file_list = self.search().filter(playbooks_id=int(self.pbid))
        else:
            file_list = self.search()
        return file_list


class DeleteBookFileView(LoginRequiredMixin, View):
    """删除剧本版本"""
    
    def get(self, request, *args, **kwargs):
        result = 0  # 0是删除失败
        try:
            fid = self.kwargs.get('fid', None)
            play_book_file = PlayBooksFile.objects.get(pk=fid)
            dire = '%s_%s' % (play_book_file.playbooks.id, play_book_file.version)
            dire_path = settings.MEDIA_ROOT + dire
            status, msg = delete_dire(dire_path)
            logger.info('文件夹%s:%s' % (dire, msg))
            result = play_book_file.update_delete()
            logger.info(u'%s删除剧本成功%s' % (request.user, fid))
        except Exception as e:
            logger.error(u'删除剧本出错,错误信息:%s' % e)
        return HttpResponse(result)


class ReplayPlayBooksView(LoginRequiredMixin, View):
    """重新运行剧本"""
    
    def post(self, request, *args, **kwargs):
        server_list = self.get_server_list()
        book_file_list = self.get_book_file()
        for i in range(len(server_list)):
            try:
                logger.info('启动celery***************')
                use_ansible.delay([server_list[i]], playbooks=book_file_list[i], variable=None)
                logger.info('结束*************************')
            except Exception as e:
                logger.error(e)
        return HttpResponse(1)
    
    def get_server_list(self):
        """获取服务器"""
        sids = self.request.POST.getlist('sid', '')
        server_list = []
        for sid in sids:
            try:
                server = Server.objects.get(pk=sid)
            except Exception as e:
                logger.error("未找到该服务器，错误:%s" % e)
            else:
                server_list.append(server)
        return server_list
    
    def get_book_file(self):
        """获取剧本"""
        pbids = self.request.POST.getlist('pbid', '')
        version_list = self.request.POST.getlist('version', '')
        book_file_list = []
        for i in range(len(pbids)):
            try:
                if version_list[i] == '未知' and pbids[i] == '更新':
                    book_file = None
                else:
                    book_file = PlayBooksFile.objects.get(version=version_list[i], playbooks_id=pbids[i])
            except Exception as e:
                logger.error("未找到该剧本，错误:%s" % e)
            else:
                book_file_list.append(book_file)
        return book_file_list


class VersionIsExistView(LoginRequiredMixin, View):
    """判断剧本是否已经存在"""

    def get(self, request, *args, **kwargs):
        result = {'code': 0, 'msg': ''}
        pbid = request.GET.get('pbid', None)
        version = request.GET.get('version', None)
        if pbid:
            is_exist = PlayBooksFile.objects.filter(playbooks=pbid, version=version).exists()
            logger.info(is_exist)
            if is_exist:
                result['msg'] = "该版本已存在"
            else:
                result['code'] = 1
        else:
            result['msg'] = "该剧本管理不存在"
        return JsonResponse(result)
